// 为体现文法支持函数调用，将文法命名为 Function。.
grammar Function;

//prog 是文法的入口， 一个 prog 有一个或多个函数定义组成。
prog: funDecl+;

// 函数定义， 有函数名 ID、 参数列表和语句块构成。
funDecl  :ID '(' paramDeclList ')' block;

// 参数列表有 0 个或多个参数定义。
paramDeclList
    :   (paramDecl (',' paramDecl)*)?;

// 参数定义对应一个词法符号 ID
paramDecl
    :   ID
;

// 语句块由花括号和语句列表组成。
block
    :  '{' stmtList '}';

// 语句列表由 0 个或多个语句组成。
stmtList:stmt*    ;

// 语句有返回语句、条件语句、三类循环语句、语句块和表达式语句组成。
stmt    options{
backtrack=true;
}      :
        RETURN expr ';'
        | ifStmt
        | WHILE '(' expr ')' stmt
        | 'do' stmt WHILE '(' expr ')'
        | 'for' '(' expr ';' expr ';' expr ')'
        | block
        | expr ';'
;

// 条件语句有 4 种形式 . if …、 if … else …、 unless …、 unless … else …。
ifStmt
options{
    backtrack=true;
}
:
     IF '(' expr ')' stmt 'else' stmt
    | 'unless' '(' expr ')' stmt 'else' stmt
    | IF '(' expr ')' stmt
| 'unless' '(' expr ')' stmt
    ;

// 表达式包含赋值表达式和逻辑或表达式。其中赋值表达式中 = 是右结合算符，使用尾递归定义文法。
expr
options{
    backtrack=true;
}
:
        ID '=' expr

        | orExpr
;
// 从逻辑或表达式开始，依据算符的优先级，依次定义了逻辑或表达式、逻辑与表达式、关系表达式、算术表达式、
// 逻辑非表达式和取反表达式。
orExpr:andExpr ('||' andExpr)*
;

andExpr:equalityExpr ('&&' equalityExpr)*
;

equalityExpr
    :   comparisonExpr (('=='|'!=') comparisonExpr)*
;

comparisonExpr
    :   additiveExpr (('>'|'<'|'<='|'>=') additiveExpr)*
;

additiveExpr
    :   multExpr (('+' |'-' ) multExpr )*
;

multExpr
    :   notExpr (('*' |'/' ) notExpr )*
;

notExpr
    :   ('!')? negationExpr
;

negationExpr
    :   ('-')? primary
;

// 基本项有原子项和用于改变运算优先级的括号加表达式构成。
primary
    :   atom
    |  '(' orExpr ')';

// 原子项有常数、函数调用和变量组成。
atom
options{
    backtrack=true;
}   :
 NUMBER
| ID '(' exprList ')'
| ID
;

// 函数调用实参列表，包含 0 个或多个表达式
exprList:   (orExpr (',' orExpr)*)?;